<template>
  <div class="collaborative-edit-page">
    <!-- 状态卡片区域 -->
    <div class="status-cards">
      <!-- 文档标题卡片 -->
      <div class="status-card document-card">
        <div class="card-header">
          <i class="fas fa-file-alt"></i>
          <span>文档标题</span>
        </div>
        <div class="card-content">
          <div class="document-title">{{ documentTitle }}</div>
          <div class="document-meta">最后编辑: {{ lastEditTime }}</div>
        </div>
      </div>

      <!-- 连接状态卡片 -->
      <div class="status-card connection-card">
        <div class="card-header">
          <i class="fas fa-wifi"></i>
          <span>连接状态</span>
        </div>
        <div class="card-content">
          <div v-if="isConnecting" class="status connecting">
            <div class="spinner"></div>
            <span>连接中...</span>
          </div>
          <div v-else-if="isConnected" class="status connected">
            <div class="indicator"></div>
            <span>已连接</span>
          </div>
          <div v-else class="status disconnected">
            <div class="indicator"></div>
            <span>未连接</span>
          </div>
        </div>
      </div>

      <!-- 在线用户卡片 -->
      <div class="status-card users-card">
        <div class="card-header">
          <i class="fas fa-users"></i>
          <span>在线用户</span>
        </div>
        <div class="card-content">
          <div class="users-count">{{ currentUsers.length }} 人在线</div>
          <div class="users-list" v-if="currentUsers.length > 0">
            <div
              v-for="item in currentUsers.slice(0, 3)"
              :key="item.name"
              class="user-avatar"
              :style="{ backgroundColor: item.color }"
              :title="item.name"
            >
              {{ item.name.charAt(0).toUpperCase() }}
            </div>
            <div v-if="currentUsers.length > 3" class="more-users">
              +{{ currentUsers.length - 3 }}
            </div>
          </div>
        </div>
      </div>

      <!-- 相关操作卡片 -->
      <div class="status-card actions-card">
        <div class="card-header">
          <i class="fas fa-cog"></i>
          <span>相关操作</span>
        </div>
        <div class="card-content">
          <div class="action-buttons">
            <button class="action-btn" @click="exportDocument">
              <i class="fas fa-download"></i>
              导出
            </button>
            <button class="action-btn" @click="shareDocument">
              <i class="fas fa-share"></i>
              分享
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- 编辑器容器 -->
    <div class="collaborative-editor-container">
      <div ref="editorRef"></div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import * as Y from 'yjs'
import { WebsocketProvider } from 'y-websocket'
import { QuillBinding } from 'y-quill'
import Quill from 'quill'
import QuillCursors from 'quill-cursors'
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import 'quill/dist/quill.snow.css'
import { useLoginUserStore } from '@/store/user'
const loginUser = useLoginUserStore()
const editorRef = ref<HTMLDivElement>()
interface collaborativeUser {
  name: string
  color: string
}
//当前在线协同编辑用户
const currentUsers = ref<collaborativeUser[]>([])
//当前在线协同编辑用户
const connectStatus = ref()
//当前用户颜色
const currentColor = ref<string>('')

// 文档相关数据
const documentTitle = ref('文档标题')
const lastEditTime = ref('2025-08-04 14:30')

// 操作方法
const exportDocument = () => {
  console.log('导出文档')
}

const shareDocument = () => {
  console.log('分享文档')
}

// 连接状态
const isConnecting = computed(() => connectStatus.value === 'connecting')
const isConnected = computed(() => connectStatus.value === 'connected')
// 协同编辑相关变量
let provider: WebsocketProvider | null = null
let ydoc: Y.Doc | null = null
let binding: any = null
let blurHandler: (() => void) | null = null
//编辑器 实例化
onMounted(() => {
  Quill.register('modules/cursors', QuillCursors)
  if (editorRef.value) {
    // create a new Quill editor
    const quill = new Quill(editorRef.value, {
      modules: {
        cursors: true,
        toolbar: [
          [{ header: [1, 2, false] }],
          ['bold', 'italic', 'underline'],
          ['image', 'code-block'],
        ],
        history: { userOnly: true },
      },
      placeholder: 'Start collaborating...',
      theme: 'snow',
    })

    // 1. 清理现有资源
    if (binding) {
      binding.destroy()
      binding = null
    }
    if (provider) {
      provider.destroy()
      provider = null
    }
    if (ydoc) {
      ydoc.destroy()
      ydoc = null
    }
    if (blurHandler) {
      window.removeEventListener('blur', blurHandler)
      blurHandler = null
    }

    // 2. 创建新的Yjs文档和WebSocket连接
    ydoc = new Y.Doc()
    provider = new WebsocketProvider('ws://localhost:8123/api/ws', 'quill-demo-room', ydoc)

    // 3. 监听连接状态
    provider.on('status', ({ status }) => {
      connectStatus.value = status
      // console.log('当前连接状态' + connectStatus.value)
    })
    const ytext = ydoc.getText('quill')
    const awareness = provider.awareness

    awareness.on('change', (changes: any) => {
      const states = Array.from(awareness.getStates().values()) as Array<{
        user?: { name: string; color: string }
      }>
      currentUsers.value = states
        .filter((s) => s?.user) // 过滤掉没有 user 字段的脏数据
        .map((s) => ({
          name: s.user!.name,
          color: s.user!.color,
        }))
      console.log('当前在线用户：', currentUsers.value)
    })
    // You can think of your own awareness information as a key-value store.
    // We update our "user" field to propagate relevant user information.
    const usercolors = [
      '#30bced',
      '#6eeb83',
      '#ffbc42',
      '#ecd444',
      '#ee6352',
      '#9ac2c9',
      '#8acb88',
      '#1be7ff',
    ]
    const myColor = usercolors[Math.floor(Math.random() * usercolors.length)]
    currentColor.value = myColor
    awareness.setLocalStateField('user', {
      // Define a print name that should be displayed
      name: loginUser.loginUser.userName,
      // Define a color that should be associated to the user:
      color: myColor, // should be a hex color
    })

    // 4. 创建Quill绑定
    binding = new QuillBinding(ytext, quill, provider.awareness)

    // 5. 处理窗口失焦事件
    blurHandler = () => {
      quill.blur()
    }
    window.addEventListener('blur', blurHandler)

  }

})
onBeforeUnmount(() => {
  // 清理绑定
  if (binding) {
    binding.destroy()
    binding = null
  }

  // 清理WebSocket连接
  if (provider) {
    provider.destroy()
    provider = null
  }

  // 清理Yjs文档
  if (ydoc) {
    ydoc.destroy()
    ydoc = null
  }

  // 清理事件监听器
  if (blurHandler) {
    window.removeEventListener('blur', blurHandler)
    blurHandler = null
  }

  // 重置状态
  connectStatus.value = 'disconnected'
  currentUsers.value = []
})
</script>

<style scoped>
:root {
  --background: #ffffff;
  --foreground: #09090b;
  --card: #ffffff;
  --card-foreground: #09090b;
  --popover: #ffffff;
  --popover-foreground: #09090b;
  --primary: #18181b;
  --primary-foreground: #fafafa;
  --secondary: #f4f4f5;
  --secondary-foreground: #18181b;
  --muted: #f4f4f5;
  --muted-foreground: #71717a;
  --accent: #f4f4f5;
  --accent-foreground: #18181b;
  --destructive: #ef4444;
  --destructive-foreground: #fafafa;
  --border: #e4e4e7;
  --input: #e4e4e7;
  --ring: #18181b;
  --radius: 0.5rem;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.collaborative-edit-page {
  min-height: 89vh;
  background: var(--background);
  font-family: 'Inter', sans-serif;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.5rem 2rem;
  background: var(--background);
  border-bottom: 1px solid var(--border);
  margin-bottom: 1.5rem;
}

.page-title {
  margin: 0;
  font-size: 1.875rem;
  font-weight: 700;
  color: var(--foreground);
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.header-actions {
  display: flex;
  gap: 0.75rem;
}

.btn {
  padding: 0.5rem 1rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: inherit;
}

.btn-primary {
  background: var(--primary);
  color: var(--primary-foreground);
  border-color: var(--primary);
}

.btn-primary:hover {
  background: #374151;
  border-color: #374151;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(24, 24, 27, 0.15);
}

.btn-secondary {
  background: var(--secondary);
  color: var(--secondary-foreground);
  border-color: var(--border);
}

.btn-secondary:hover {
  background: var(--muted);
  border-color: var(--ring);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.btn-icon {
  width: 2.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--background);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  transition: all 0.3s ease;
}

.btn-icon:hover {
  background: var(--accent);
  border-color: var(--ring);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

/* 状态卡片区域 */
.status-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  padding: 0 2rem;
  margin-bottom: 1.5rem;
  margin-top: 2rem;
}

.status-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 0.75rem;
  padding: 1.25rem;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
}

.status-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
  border-color: var(--primary);
}

.card-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  color: var(--muted-foreground);
  font-size: 0.875rem;
  font-weight: 500;
}

.card-header i {
  font-size: 1rem;
}

.card-content {
  color: var(--foreground);
}

/* 文档标题卡片 */
.document-card .document-title {
  font-size: 1.125rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
  color: var(--foreground);
}

.document-card .document-meta {
  font-size: 0.75rem;
  color: var(--muted-foreground);
}

/* 连接状态卡片 */
.connection-card .status {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 500;
}

.connection-card .status.connected {
  color: #059669;
}

.connection-card .status.connecting {
  color: #d97706;
}

.connection-card .status.disconnected {
  color: #dc2626;
}

/* 在线用户卡片 */
.users-card .users-count {
  font-size: 1.125rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
  color: var(--foreground);
}

.users-card .users-list {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.users-card .user-avatar {
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: 600;
  font-size: 0.75rem;
  border: 2px solid rgba(255, 255, 255, 0.2);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.users-card .more-users {
  background: var(--muted);
  color: var(--muted-foreground);
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.625rem;
  font-weight: 600;
  border: 1px solid var(--border);
}

/* 相关操作卡片 */
.actions-card .action-buttons {
  display: flex;
  gap: 0.5rem;
}

.action-btn {
  flex: 1;
  padding: 0.5rem 0.75rem;
  background: var(--secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--secondary-foreground);
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
}

.action-btn:hover {
  background: var(--accent);
  border-color: var(--ring);
  transform: translateY(-1px);
}

.collaborative-editor-container {
  margin: 0 2rem 2rem;
  background: var(--card);
  border-radius: 0.75rem;
  border: 1px solid var(--border);
  box-shadow:
    0 4px 6px -1px rgba(0, 0, 0, 0.1),
    0 2px 4px -1px rgba(0, 0, 0, 0.06);
  overflow: hidden;
}

.indicator {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: currentColor;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

.spinner {
  width: 0.875rem;
  height: 0.875rem;
  border: 2px solid currentColor;
  border-top: 2px solid transparent;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* Quill Editor Overrides */
:deep(.ql-toolbar) {
  border-top: none;
  border-left: none;
  border-right: none;
  border-bottom: 1px solid var(--border);
  background: var(--muted);
  padding: 1rem;
}

:deep(.ql-container) {
  border: none;
  font-family: 'Inter', sans-serif;
}

:deep(.ql-editor) {
  padding: 2rem;
  font-size: 1rem;
  line-height: 1.7;
  color: var(--foreground);
  min-height: 500px;
}

:deep(.ql-editor h1) {
  font-size: 2.25rem;
  font-weight: 700;
  margin-bottom: 1.5rem;
  color: var(--foreground);
}

:deep(.ql-editor h2) {
  font-size: 1.875rem;
  font-weight: 600;
  margin-bottom: 1rem;
  margin-top: 2rem;
  color: var(--foreground);
}

:deep(.ql-editor p) {
  margin-bottom: 1rem;
  color: var(--foreground);
}

:deep(.ql-editor ul, .ql-editor ol) {
  margin-bottom: 1rem;
  padding-left: 2rem;
}

:deep(.ql-editor li) {
  margin-bottom: 0.5rem;
}

:deep(.ql-snow .ql-tooltip) {
  background: var(--popover);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}

/* Responsive Design */
@media (max-width: 1024px) {
  .status-cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 768px) {
  .page-header {
    padding: 1rem;
    flex-direction: column;
    gap: 1rem;
    align-items: flex-start;
  }

  .page-title {
    font-size: 1.5rem;
  }

  .status-cards {
    grid-template-columns: 1fr;
    padding: 0 1rem;
  }

  .status-card {
    padding: 1rem;
  }

  .collaborative-editor-container {
    margin: 0 1rem 1rem;
  }

  :deep(.ql-editor) {
    padding: 1rem;
  }

  .action-buttons {
    flex-direction: column;
  }
}
</style>
